package com.starrocks.log;

import lombok.Data;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Consumer;

/**
 * 日志收集器（单例）
 * 收集系统日志并推送给订阅者
 */
@Component
public class LogCollector {
    
    /**
     * 日志缓冲区（最多保存最近的1000条日志）
     */
    private static final int MAX_LOG_SIZE = 1000;
    private final ConcurrentLinkedQueue<LogMessage> logBuffer = new ConcurrentLinkedQueue<>();
    
    /**
     * 日志订阅者列表
     */
    private final CopyOnWriteArrayList<Consumer<LogMessage>> subscribers = new CopyOnWriteArrayList<>();
    
    /**
     * 添加日志
     */
    public void addLog(String level, String logger, String message, String thread) {
        LogMessage logMsg = new LogMessage(level, logger, message, thread);
        
        // 添加到缓冲区
        logBuffer.offer(logMsg);
        
        // 超过最大容量，移除最早的日志
        while (logBuffer.size() > MAX_LOG_SIZE) {
            logBuffer.poll();
        }
        
        // 推送给所有订阅者
        for (Consumer<LogMessage> subscriber : subscribers) {
            try {
                subscriber.accept(logMsg);
            } catch (Exception e) {
                // 订阅者处理失败，移除该订阅者
                subscribers.remove(subscriber);
            }
        }
    }
    
    /**
     * 订阅日志
     */
    public void subscribe(Consumer<LogMessage> consumer) {
        subscribers.add(consumer);
    }
    
    /**
     * 取消订阅
     */
    public void unsubscribe(Consumer<LogMessage> consumer) {
        subscribers.remove(consumer);
    }
    
    /**
     * 获取历史日志（最近的N条）
     */
    public ConcurrentLinkedQueue<LogMessage> getHistoryLogs() {
        return new ConcurrentLinkedQueue<>(logBuffer);
    }
    
    /**
     * 获取订阅者数量
     */
    public int getSubscriberCount() {
        return subscribers.size();
    }
    
    /**
     * 日志消息
     */
    @Data
    public static class LogMessage {
        private final String timestamp;
        private final String level;
        private final String logger;
        private final String message;
        private final String thread;
        
        public LogMessage(String level, String logger, String message, String thread) {
            this.timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"));
            this.level = level;
            this.logger = logger;
            this.message = message;
            this.thread = thread;
        }
        
        /**
         * 转换为JSON字符串（手动拼接，避免依赖）
         */
        public String toJson() {
            return String.format("{\"timestamp\":\"%s\",\"level\":\"%s\",\"logger\":\"%s\",\"message\":\"%s\",\"thread\":\"%s\"}",
                escapeJson(timestamp),
                escapeJson(level),
                escapeJson(logger),
                escapeJson(message),
                escapeJson(thread)
            );
        }
        
        /**
         * 转换为纯文本格式
         */
        public String toText() {
            return String.format("%s [%s] %s - %s - %s",
                timestamp, thread, level, logger, message);
        }
        
        private String escapeJson(String str) {
            if (str == null) {
                return "";
            }
            return str.replace("\\", "\\\\")
                     .replace("\"", "\\\"")
                     .replace("\n", "\\n")
                     .replace("\r", "\\r")
                     .replace("\t", "\\t");
        }
    }
}

